package main

import "fmt"

var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
var slice0 []int = arr[2:8]
var slice1 []int = arr[0:6]        //可以简写为 var slice []int = arr[:end]
var slice2 []int = arr[5:10]       //可以简写为 var slice[]int = arr[start:]
var slice3 []int = arr[0:len(arr)] //var slice []int = arr[:]
var slice4 = arr[:len(arr)-1]      //去掉切片的最后一个元素

var slice10 []int = make([]int, 10)
var slice11 = make([]int, 10)
var slice12 = make([]int, 10, 10)

func main() {
	//1.声明切片
	var s1 []int
	if s1 == nil {
		fmt.Println("是空")
	} else {
		fmt.Println("不是空")
	}
	// 2.:=
	s2 := []int{}
	// 3.make()
	var s3 []int = make([]int, 0)
	fmt.Println(s1, s2, s3)
	// 4.初始化赋值
	var s4 []int = make([]int, 0, 2)
	fmt.Println(s4)
	s5 := []int{1, 2, 3}
	fmt.Println(s5)
	// 5.从数组切片
	arr0 := [5]int{1, 2, 3, 4, 5}
	var s6 []int
	// 前包后不包
	s6 = arr0[1:4]
	fmt.Println(s6)


	fmt.Printf("全局变量: arr %v\n", arr)
    fmt.Printf("全局变量: slice0 %v\n", slice0)
    fmt.Printf("全局变量: slice1 %v\n", slice1)
    fmt.Printf("全局变量: slice2 %v\n", slice2)
    fmt.Printf("全局变量: slice3 %v\n", slice3)
    fmt.Printf("全局变量: slice4 %v\n", slice4)
    fmt.Printf("-----------------------------------\n")
    arr2 := [...]int{9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
    slice5 := arr2[2:8]
    slice6 := arr2[0:6]         //可以简写为 slice := arr[:end]
    slice7 := arr2[5:10]        //可以简写为 slice := arr[start:]
    slice8 := arr2[0:len(arr)]  //slice := arr[:]
    slice9 := arr2[:len(arr)-1] //去掉切片的最后一个元素
    fmt.Printf("局部变量： arr2 %v\n", arr2)
    fmt.Printf("局部变量： slice5 %v\n", slice5)
    fmt.Printf("局部变量： slice6 %v\n", slice6)
    fmt.Printf("局部变量： slice7 %v\n", slice7)
    fmt.Printf("局部变量： slice8 %v\n", slice8)
    fmt.Printf("局部变量： slice9 %v\n", slice9)
	fmt.Printf("-----------------------------------\n")

	fmt.Printf("make全局slice10 ：%v\n", slice10)
    fmt.Printf("make全局slice11 ：%v\n", slice11)
    fmt.Printf("make全局slice12 ：%v\n", slice12)
    fmt.Println("--------------------------------------")
    slice13 := make([]int, 10)
    slice14 := make([]int, 10)
    slice15 := make([]int, 10, 10)
    fmt.Printf("make局部slice13 ：%v\n", slice13)
    fmt.Printf("make局部slice14 ：%v\n", slice14)
    fmt.Printf("make局部slice15 ：%v\n", slice15)
	fmt.Println("--------------------------------------")

	data := [...]int{0, 1, 2, 3, 4, 5}

    s := data[2:4]
    s[0] += 100
    s[1] += 200

    fmt.Println(s)
    fmt.Println(data)
	fmt.Println("--------------------------------------")

	s31 := []int{0, 1, 2, 3, 8: 100} // 通过初始化表达式构造，可使用索引号。
    fmt.Println(s31, len(s31), cap(s31))

    s32 := make([]int, 6, 8) // 使用 make 创建，指定 len 和 cap 值。
    fmt.Println(s32, len(s32), cap(s32))

    s33 := make([]int, 6) // 省略 cap，相当于 cap = len。
    fmt.Println(s33, len(s33), cap(s33))
	fmt.Println("--------------------------------------")

	s40 := []int{0, 1, 2, 3}
    p := &s40[2] // *int, 获取底层数组元素指针。
    *p += 100

    fmt.Println(s40)
	fmt.Println("--------------------------------------")

	data1 := [][]int{
        []int{1, 2, 3},
        []int{100, 200},
        []int{11, 22, 33, 44},
    }
    fmt.Println(data1)


	d := [5]struct {
        x int
    }{}

    s41 := d[:]

    d[1].x = 10
    s41[2].x = 20

    fmt.Println(d)
    fmt.Printf("%p, %p\n", &d, &d[0])

	var a = []int{1, 2, 3}
    fmt.Printf("slice a : %v\n", a)
    var b = []int{4, 5, 6}
    fmt.Printf("slice b : %v\n", b)
    c := append(a, b...)
    fmt.Printf("slice c : %v\n", c)
    d1 := append(c, 7)
    fmt.Printf("slice d1 : %v\n", d1)
    e := append(d1, 8, 9, 10)
    fmt.Printf("slice e : %v\n", e)
	fmt.Println("--------------------------------------")

	s51 := make([]int, 0, 5)
    fmt.Printf("%p\n", &s51)

    s52 := append(s51, 1)
    fmt.Printf("%p\n", &s52)

    fmt.Println(s51, s52)
	fmt.Println("--------------------------------------")

	data61 := [...]int{0, 1, 2, 3, 4, 10: 0}
    s61 := data61[:2:3]
	fmt.Println(s61)
	fmt.Println(&s61[0])
    s61 = append(s61, 100, 200) // 一次 append 两个值，超出 s.cap 限制。

    fmt.Println(s61, data61)         // 重新分配底层数组，与原数组无关。
    fmt.Println(&s61[0], &data61[0]) // 比对底层数组起始指针。
	fmt.Println("--------------------------------------")

	s66 := make([]int, 0, 3)
    c66 := cap(s66)

    for i := 0; i < 50; i++ {
        s66 = append(s66, i)
        if n := cap(s66); n > c66 {
            fmt.Printf("cap: %d -> %d\n", c66, n)
            c66 = n
        }
    }

}
